﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Xml;
using System.Windows.Media;
using System.Windows;
using System.Windows.Documents;
using System.IO;
using System.Windows.Input;

namespace SHomeWorkshop.LunarMind
{
    public class RecentFileItem : Border
    {
        public static void WriteRecentFilesToXmlFile(string newFullPathFilename)
        {
            if (Directory.Exists(Globals.pathOfUserDirectory) == false)
            {
                Directory.CreateDirectory(Globals.pathOfUserDirectory);
            }

            if (Directory.Exists(Globals.pathOfUserDirectory) == false)
            {
                MessageBox.Show("未能创建用户目录，不能写入“最近使用的文档列表”到磁盘。",
                    Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            if (newFullPathFilename == null || newFullPathFilename.Length <= 0)
            {
                MessageBox.Show("不能将空文件路径写入“最近使用的文档列表”到磁盘。",
                    Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            if (newFullPathFilename.ToLower().EndsWith(".lunarmind") == false &&
                newFullPathFilename.ToLower().EndsWith(".png") == false)
            {
                return;//只有这两种后缀名才会记载。避免意外错误。
            }

            XmlDocument xDoc = XmlTools.LoadXmlFile(Globals.pathOfRecentlyFiles);

            if (xDoc == null)
            {
                xDoc = new XmlDocument();
                xDoc.LoadXml(Properties.Resources.RecentFilesXml);
            }

            if (xDoc == null)
            {
                MessageBox.Show("未找到“最近使用的文档列表”文档，且未能创建。",
                   Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            if (xDoc.DocumentElement == null)
            {
                xDoc.CreateElement("RecentFiles");
            }

            if (xDoc.DocumentElement == null)
            {
                MessageBox.Show("未找到“最近使用的文档列表”文档根节点，且未能创建。",
                   Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            XmlNodeList nodes = xDoc.DocumentElement.SelectNodes("FullPathFileName");

            if (nodes.Count <= 0)
            {
                xDoc.DocumentElement.InnerXml = "<FullPathFileName>" + newFullPathFilename + "</FullPathFileName>";
                xDoc.Save(Globals.pathOfRecentlyFiles);
                return;
            }
            else
            {
                for (int i = nodes.Count - 1; i >= 0; i--)
                {
                    XmlNode node = nodes[i];
                    if (node.InnerText == newFullPathFilename)
                    {
                        xDoc.DocumentElement.RemoveChild(node);
                        break;
                    }
                }

                xDoc.DocumentElement.InsertXmlAt("<FullPathFileName>" + newFullPathFilename + "</FullPathFileName>", 0);
                xDoc.Save(Globals.pathOfRecentlyFiles);
                return;
            }
        }

        public static void ReadRecentFilesFromXmlFile()
        {
            string xmlFilePath = Globals.pathOfRecentlyFiles;

            XmlDocument xDoc;

            if (File.Exists(xmlFilePath) == false)
            {
                xDoc = XmlTools.SaveToXmlFile(xmlFilePath, Properties.Resources.RecentFilesXml);
            }
            else
            {
                xDoc = XmlTools.LoadXmlFile(xmlFilePath);
            }

            Globals.MainWindow.spRecentFiles.Children.Clear();

            if (xDoc.DocumentElement == null || xDoc.DocumentElement.Name != "RecentFiles")
            {
                Globals.MainWindow.spRecentFiles.Children.Add(
                    new TextBlock() { Text = "..最近文件列表文件格式错误.." }
                    );
                return;
            }

            XmlNodeList nodes = xDoc.DocumentElement.SelectNodes("FullPathFileName");

            if (nodes.Count <= 0)
            {
                Globals.MainWindow.spRecentFiles.Children.Add(
                    new TextBlock() { Text = "..尚无最近文件列表.." }
                    );
                return;
            }

            foreach (XmlNode node in nodes)
            {
                if (node.InnerText.ToLower().EndsWith(".lunarmind") ||
                    node.InnerText.ToLower().EndsWith(".png"))
                {
                    RecentFileItem rfi = new RecentFileItem(node.InnerText);
                    Globals.MainWindow.spRecentFiles.Children.Add(rfi);
                    rfi.IsCheckedChanged += rfi_IsCheckedChanged;
                }//只应该读取两种后缀名。否则容易引起意外错误。
            }
        }

        static void rfi_IsCheckedChanged(object sender, RecentFileItemIsCheckedChangedEventArgs e)
        {
            if (e.NewCheckedValue == true)
            {
                foreach (UIElement ue in Globals.MainWindow.spRecentFiles.Children)
                {
                    RecentFileItem rfi = ue as RecentFileItem;
                    if (rfi == null || rfi == sender) continue;

                    rfi.IsChecked = false;//最近文件项目互斥选中状态。
                }
            }
        }

        private TextBlock mainTextBlock = new TextBlock();

        private static Thickness padding = new Thickness(5);

        private static Thickness marging = new Thickness(4);

        private static Thickness borderWidth = new Thickness(1);

        private bool isChecked = false;

        public event EventHandler<RecentFileItemIsCheckedChangedEventArgs> IsCheckedChanged;

        protected void OnIsCheckedChanged(object sender, RecentFileItemIsCheckedChangedEventArgs e)
        {
            if (IsCheckedChanged != null)
            {
                IsCheckedChanged(this, e);
            }
        }

        public bool IsChecked
        {
            get { return isChecked; }
            set
            {
                if (value)
                {
                    this.mainTextBlock.Background = SystemColors.MenuHighlightBrush;
                    this.mainTextBlock.Foreground = SystemColors.HighlightTextBrush;
                }
                else
                {
                    this.mainTextBlock.Foreground = SystemColors.MenuTextBrush;
                    this.mainTextBlock.Background = SystemColors.MenuBrush;
                }

                OnIsCheckedChanged(this, new RecentFileItemIsCheckedChangedEventArgs()
                {
                    OldCheckedValue = isChecked,
                    NewCheckedValue = value,
                });

                isChecked = value;
            }
        }

        public RecentFileItem(string fullPathFileName)
            : base()
        {
            this.BorderBrush = Brushes.DarkGreen;
            this.BorderThickness = RecentFileItem.borderWidth;
            this.SnapsToDevicePixels = true;
            this.HorizontalAlignment = HorizontalAlignment.Center;
            this.HorizontalAlignment = HorizontalAlignment.Stretch;

            this.Child = mainTextBlock;

            this.Margin = RecentFileItem.marging;
            this.mainTextBlock.ToolTip = "双击打开文件\r\n按Shift双击在新窗口打开";

            this.FullPathFileName = fullPathFileName;

            this.mainTextBlock.Padding = RecentFileItem.padding;

            this.mainTextBlock.TextWrapping = TextWrapping.Wrap;
            this.mainTextBlock.Foreground = SystemColors.MenuTextBrush;
            this.mainTextBlock.Background = SystemColors.MenuBrush;

            this.PreviewMouseLeftButtonDown += RecentFileItem_PreviewMouseLeftButtonDown;
        }

        void RecentFileItem_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            this.IsChecked = true;

            if (e.ClickCount != 2) return;

            //双击打开文档。
            if (File.Exists((sender as RecentFileItem).fullPathFileName) == false)
            {
                MessageBoxResult mbr = MessageBox.Show("此文件已不在原磁盘位置。要删除此条目吗？",
                    Globals.AppName, MessageBoxButton.YesNo, MessageBoxImage.Warning);

                if (mbr == MessageBoxResult.Yes)
                {
                    XmlDocument xDoc = XmlTools.LoadXmlFile(Globals.pathOfRecentlyFiles);

                    if (xDoc == null || xDoc.DocumentElement == null) return;
                    XmlNodeList nodes = xDoc.DocumentElement.SelectNodes("FullPathFileName");
                    if (nodes == null || nodes.Count <= 0) return;

                    for (int i = nodes.Count - 1; i >= 0; i--)
                    {
                        XmlNode node = nodes[i];
                        if (node.InnerText == (sender as RecentFileItem).FullPathFileName)
                        {
                            xDoc.DocumentElement.RemoveChild(node);
                        }
                    }

                    xDoc.Save(Globals.pathOfRecentlyFiles);
                    RecentFileItem.ReadRecentFilesFromXmlFile();
                    return;
                }
                else if (mbr == MessageBoxResult.No) return;
            }

            KeyStates ksLeft = Keyboard.GetKeyStates(Key.LeftShift);
            KeyStates ksRight = Keyboard.GetKeyStates(Key.RightShift);

            bool isShift = false;

            if ((ksLeft & KeyStates.Down) > 0 || (ksRight & KeyStates.Down) > 0)
            {
                isShift = true;
            }

            if (isShift)
            {
                System.Diagnostics.Process newProcess = System.Diagnostics.Process.Start(Globals.fullPathOfApp,
                     "\"" + (sender as RecentFileItem).fullPathFileName + "\"");
                //前后不加引号，会导致带空格的路径无法解析。

                e.Handled = true;
                return;
            }
            else
            {
                if (Globals.MainWindow.IsModified)
                {
                    MessageBoxResult mr = MessageBox.Show("当前文档已被修改，要保存吗？", Globals.AppName,
                        MessageBoxButton.YesNoCancel, MessageBoxImage.Warning, MessageBoxResult.Yes);

                    switch (mr)
                    {
                        case MessageBoxResult.Yes:
                            {
                                if (Commands.SaveDocumentCommand.SaveDocument())
                                {
                                    OpenDocument(fullPathFileName);
                                }
                                else return;

                                break;
                            }
                        case MessageBoxResult.No:
                            {
                                OpenDocument(fullPathFileName);
                                break;
                            }
                        default:
                            {
                                return;//其余都作Cancel看待。
                            }
                    }
                }
                else
                {
                    OpenDocument(fullPathFileName);
                }
            }

            //打开文件后，关闭右工具栏。
            Globals.MainWindow.rightToolGridColumn.Width = new GridLength(0);
            Globals.MainWindow.TryToScrollRootTitleAtCenter();//右工具栏的关闭会导致ScrollViewer视口尺寸变化，此时根标题中心位置会偏移，再执行一次就没问题了。

            Globals.MainWindow.tcRightTools.SelectedIndex = 0;//选中“图标库”页面。
        }

        private static void OpenDocument(string filename)
        {
            if (filename.EndsWith(".lunarmind"))
            {
                Commands.OpenDocumentCommand.ReadDocumentFromDiskFile(filename);

                RecentFileItem.WriteRecentFilesToXmlFile(filename);
                RecentFileItem.ReadRecentFilesFromXmlFile();
            }
            else if (filename.EndsWith(".png"))
            {
                Commands.OpenDocumentCommand.ReadOutportedPNGImageFile(filename);

                RecentFileItem.WriteRecentFilesToXmlFile(filename);
                RecentFileItem.ReadRecentFilesFromXmlFile();
            }
            else
            {
                MessageBox.Show("不支持这种类型的文件！请检查文件后缀名，并确定此文件是由《" + Globals.AppName + "》生成的。",
                    Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }
        }


        /// <summary>
        /// 返回文件短名。
        /// </summary>
        public string ShortFileName
        {
            get
            {
                if (fullPathFileName == null) return null;

                if (fullPathFileName.Length <= 0) return null;

                int index = fullPathFileName.LastIndexOf('\\');

                if (index < 0)
                {
                    return fullPathFileName;
                }
                else
                {
                    return fullPathFileName.Substring(index + 1);
                }
            }
        }

        private string fullPathFileName;

        public string FullPathFileName
        {
            get { return fullPathFileName; }
            set
            {
                this.mainTextBlock.Inlines.Clear();

                fullPathFileName = value;

                Span fileSpan = new Span() { Foreground = SystemColors.ActiveCaptionTextBrush };
                Run fileRun = new Run("◆◆文件：" + ShortFileName);
                fileSpan.Inlines.Add(fileRun);

                Span pathSpan = new Span() { Foreground = SystemColors.ControlTextBrush };
                Run pathRun = new Run("◇◇路径：" + FullPathFileName);
                pathSpan.Inlines.Add(pathRun);

                this.mainTextBlock.Inlines.Add(fileSpan);
                this.mainTextBlock.Inlines.Add(new LineBreak());
                this.mainTextBlock.Inlines.Add(pathSpan);
            }
        }

        internal void OpenDocument(bool isShift)
        {
            OpenDocument(this.FullPathFileName);
        }
    }
}
